﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Shinva.Variables.Helper
{
    /// <summary>
    /// 工具帮助类，用于检查和修正生成的变量名，确保符合C语言变量命名规范。
    /// 包括：检查特殊符号、替换特殊符号、判断C关键字、以及修正首字符等。
    /// </summary>
    public static class CVariableNameUtil
    {
        // C 语言关键字列表（忽略大小写检查）
        private static readonly HashSet<string> cKeywords = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
    {
        "auto", "break", "case", "char", "const", "continue",
        "default", "do", "double", "else", "enum", "extern",
        "float", "for", "goto", "if", "inline", "int", "long",
        "register", "restrict", "return", "short", "signed",
        "sizeof", "static", "struct", "switch", "typedef",
        "union", "unsigned", "void", "volatile", "while",
        // C11 关键字
        "_alignas", "_alignof", "_atomic", "_bool", "_complex",
        "_generic", "_imaginary", "_noreturn", "_static_assert", "_thread_local"
    };

        /// <summary>
        /// 判断字符串中是否包含特殊符号（非字母、数字、下划线）
        /// </summary>
        public static bool HasSpecialSymbols(string name)
        {
            foreach (char c in name)
            {
                if (!(char.IsLetterOrDigit(c) || c == '_'))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 替换字符串中除字母、数字、下划线以外的所有字符为下划线
        /// </summary>
        public static string ReplaceSpecialSymbols(string name)
        {
            StringBuilder sb = new StringBuilder();
            foreach (char c in name)
            {
                if (char.IsLetterOrDigit(c) || c == '_')
                {
                    sb.Append(c);
                }
                else
                {
                    sb.Append('_');
                }
            }
            return sb.ToString();
        }

        /// <summary>
        /// 检查并修正生成的变量名
        /// 1. 替换特殊符号
        /// 2. 如果首字符不是字母或下划线，则在前面加下划线
        /// 3. 如果生成的变量名为 C 语言关键字，则追加下划线进行修正
        /// </summary>
        public static string EnsureValidIdentifier(string name)
        {
            // 替换特殊字符
            name = ReplaceSpecialSymbols(name);

            // 如果为空，则默认返回下划线
            if (string.IsNullOrEmpty(name))
            {
                name = "_";
            }

            // 确保首字符为字母或下划线
            if (!(char.IsLetter(name[0]) || name[0] == '_'))
            {
                name = "_" + name;
            }

            // 正则表达式校验：^[A-Za-z_][A-Za-z0-9_]*$
            Regex regex = new Regex(@"^[A-Za-z_][A-Za-z0-9_]*$");
            if (!regex.IsMatch(name))
            {
                // 如果不合法，则再次替换特殊符号并修正首字符
                name = "_" + name;
            }

            // 检查是否为 C 关键字，如果是则追加下划线
            if (cKeywords.Contains(name))
            {
                name = name + "_";
            }
            return name;
        }
    }

}
